package ru.ifmo.swing.genetics.selection;

import org.uncommons.maths.random.Probability;
import org.uncommons.watchmaker.framework.EvaluatedCandidate;
import org.uncommons.watchmaker.framework.SelectionStrategy;
import org.uncommons.watchmaker.framework.selection.TournamentSelection;
import org.uncommons.watchmaker.swing.ProbabilityParameterControl;
import ru.ifmo.swing.EvolutionControlWithConfigProvider;
import ru.ifmo.swing.Panel;

import javax.swing.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @author avhaliullin
 */
public class TournamentControl implements EvolutionControlWithConfigProvider, SelectionStrategy<Object> {
    private final TournamentSelection selection;

    public Map<String, Object> getParamValues() {
        Map<String, Object> res = new HashMap<String, Object>();
        res.put("Probability", probabilityControl.getNumberGenerator().nextValue());
        return res;
    }

    private final ProbabilityParameterControl probabilityControl;
    private final Panel control;

    public TournamentControl(double defaultProbability) {
        probabilityControl = new ProbabilityParameterControl(
                Probability.EVENS,
                Probability.ONE,
                2,
                new Probability(defaultProbability));
        control = new Panel();
        control.add(probabilityControl.getControl());
        selection = new TournamentSelection(probabilityControl.getNumberGenerator());
    }

    public JComponent getControl() {
        return control;
    }

    public void reset() {
        probabilityControl.reset();
    }

    public void setDescription(String description) {
        control.setTitle(description);
    }

    public <S> List<S> select(List<EvaluatedCandidate<S>> population, boolean naturalFitnessScores, int selectionSize, Random rng) {
        return selection.select(population, naturalFitnessScores, selectionSize, rng);
    }
}
